/* eslint-disable no-restricted-globals */
/* eslint-disable default-param-last */
/* eslint-disable no-param-reassign */
import {
  ControlVO,
  GridController,
  GridRowState,
  IMDControlController,
} from '@ibiz-template/runtime';
import { chunk } from 'lodash-es';
import dayjs from 'dayjs';
import { listenJSEvent } from '@ibiz-template/core';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
import weekOfYear from 'dayjs/plugin/weekOfYear';

dayjs.extend(quarterOfYear);
dayjs.extend(weekOfYear);

/**
 * 通过回车聚焦元素
 *
 * @export
 * @param {(HTMLElement | Document)} [target=document] 聚焦元素范围 默认document
 * @param {string[]} [querySelects=[
 *     'a',
 *     'input',
 *     'button',
 *     'textarea',
 *     'select',
 *     '[tabindex]:not([tabindex="-1"])',
 *   ]] 可聚焦元素选择器
 * @param {() => void} [callback] 最后一个可聚焦元素回车事件回调
 * @return {*}  {{
 *   cleanup: () => void;
 * }}
 */
export function useFocusByEnter(
  target: HTMLElement | Document = document,
  querySelects: string[] = [
    'a',
    'input',
    'button',
    'textarea',
    'select',
    '[tabindex]:not([tabindex="-1"])',
  ],
  callback?: () => void,
): {
  cleanup: () => void;
} {
  const querySelector = querySelects.join(',');
  const listener = (event: KeyboardEvent): void => {
    if (event.key === 'Enter') {
      // 阻止默认行为
      event.preventDefault();
      const currentElement = document.activeElement as HTMLElement;
      // 获取所有可聚焦元素
      const focusableElements = Array.from(
        target.querySelectorAll(querySelector),
      ) as HTMLElement[];
      const currentIndex = focusableElements.indexOf(currentElement);
      const nextElement = focusableElements[currentIndex + 1];
      if (nextElement) {
        // 聚焦到下一个元素
        nextElement.focus();
      } else {
        callback?.();
      }
    }
  };
  const cleanup = listenJSEvent(window, 'keydown', listener, {
    capture: true,
  });
  return { cleanup };
}

/**
 * 使用分页组件
 *
 * @author lxm
 * @date 2022-09-06 17:09:09
 * @export
 * @param {GridController} c
 * @returns {*}
 */
export function usePagination(c: IMDControlController): {
  onPageChange: (page: number) => void;
  onPageSizeChange: (size: number) => void;
  onPageRefresh: () => void;
} {
  // 初始化表格项
  const initGridItems = (): void => {
    const controller = c as GridController;
    if (Array.isArray(controller.state.simpleData)) {
      controller.state.items =
        chunk(controller.state.simpleData, controller.state.size)[
          controller.state.curPage - 1
        ] || [];
      controller.state.rows = controller.state.items.map(item => {
        const row = new GridRowState(new ControlVO(item), controller);
        return row;
      });
    }
  };

  function onPageChange(page: number): void {
    if (!page || page === c.state.curPage) return;
    c.state.curPage = page;
    if (c.runMode === 'DESIGN') {
      initGridItems();
      return;
    }
    c.load();
  }

  function onPageSizeChange(size: number): void {
    if (!size || size === c.state.size) return;
    c.state.size = size;
    if (c.runMode === 'DESIGN') {
      initGridItems();
      return;
    }
    // 当page为第一页的时候切换size不会触发pageChange，需要自己触发加载
    if (c.state.curPage !== 1) c.state.curPage = 1;
    c.load();
  }

  function onPageRefresh(): void {
    c.load();
  }
  return { onPageChange, onPageSizeChange, onPageRefresh };
}

/**
 * @description 获取时间范围
 * @export
 * @param {string} val
 * @param {('year' | 'quarter' | 'month' | 'week' | 'day')} format
 * @returns {*}  {({
 *       start: string;
 *       end: string;
 *     }
 *   | undefined)}
 */
export function getDateRange(
  val: string,
  type?: 'year' | 'quarter' | 'month' | 'week' | 'day',
):
  | {
      start: string;
      end: string;
    }
  | undefined {
  if (!val || isNaN(new Date(val).getTime()) || !type) return;
  let date = dayjs(val);
  switch (type) {
    case 'year':
      date = date.year(date.year());
      break;
    case 'quarter':
      date = date.quarter(date.quarter());
      break;
    case 'month':
      date = date.month(date.month());
      break;
    case 'week':
      date = date.week(date.week());
      break;
    case 'day':
      date = date.date(date.date());
      break;
    default:
      break;
  }
  return {
    start: date.startOf(type).format('YYYY-MM-DD HH:mm:ss'),
    end: date.endOf(type).format('YYYY-MM-DD HH:mm:ss'),
  };
}

/**
 * @description 格式化时间
 * @export
 * @param {string} val
 * @param {('year' | 'quarter' | 'month' | 'week' | 'day')} format
 * @returns {*}  {string}
 */
export function formatDate(
  val: string,
  format: 'year' | 'quarter' | 'month' | 'week' | 'day',
): string {
  let value = val;
  const date = new Date(val);
  if (!val || isNaN(date.getTime())) return value;
  const year = dayjs(date).year();
  switch (format) {
    case 'year':
      value = `${year}`;
      break;
    case 'quarter':
      value = `${year} ${dayjs(date).quarter()}${ibiz.i18n.t('runtime.controller.utils.util.quarter')}`;
      break;
    case 'month':
      value = `${year} ${dayjs(date).month() + 1}${ibiz.i18n.t('runtime.controller.utils.util.month')}`;
      break;
    case 'week':
      value = `${year} ${dayjs(date).week()}${ibiz.i18n.t('runtime.controller.utils.util.week')}`;
      break;
    case 'day':
      value = dayjs(date).format('YYYY-MM-DD');
      break;
    default:
      break;
  }
  return value;
}
